package com.nnnu.orange.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nnnu.orange.constant.BookStatusConstants;
import com.nnnu.orange.constant.MessageConstants;
import com.nnnu.orange.exception.ObjectNullException;
import com.nnnu.orange.mapper.BooksMapper;
import com.nnnu.orange.mapper.CategoriesMapper;
import com.nnnu.orange.pojo.dto.CategoriesQueryDto;
import com.nnnu.orange.pojo.dto.CategoryDto;
import com.nnnu.orange.pojo.entity.Books;
import com.nnnu.orange.pojo.entity.Categories;
import com.nnnu.orange.result.PageResult;
import com.nnnu.orange.service.ICategoriesService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 存储图书类别信息 服务实现类
 * </p>
 *
 * @author zk
 * @since 2024-11-07
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class CategoriesServiceImpl extends ServiceImpl<CategoriesMapper, Categories> implements ICategoriesService {

    private final BooksMapper booksMapper;

    /**
     * 新增图书分类
     *
     * @param categoryDto 图书分类 DTO 对象
     */
    @Override
    public void save(CategoryDto categoryDto) {
        Categories categories = BeanUtil.copyProperties(categoryDto, Categories.class);
        categories.setCreatedAt(LocalDateTime.now());
        categories.setUpdatedAt(LocalDateTime.now());
        baseMapper.insert(categories);
    }

    /**
     * 修改图书分类
     *
     * @param categoryDto 图书分类dto
     */
    @Override
    public void update(CategoryDto categoryDto) {
        if (categoryDto == null) {
            throw new ObjectNullException(MessageConstants.NULL);
        }
        baseMapper.updateById(BeanUtil.copyProperties(categoryDto, Categories.class));
    }


    /**
     * 分页获取图书分类列表
     *
     * @param queryDto dto
     * @return 分页后的dto
     */
    @Override
    public PageResult<Categories> list(@NotNull CategoriesQueryDto queryDto) {
        String name = queryDto.getName();
        String description = queryDto.getDescription();

        // 检查分页参数
        boolean isPagination = queryDto.getPageNum() != null && queryDto.getPageSize() != null && queryDto.getPageNum() > 0 && queryDto.getPageSize() > 0;

        // 创建分页对象，如果不分页，则创建一个默认的分页（查询全部数据）
        Page<Categories> categoriesPage;
        if (isPagination) {
            categoriesPage = baseMapper.selectPage(new Page<>(queryDto.getPageNum(),
                            queryDto.getPageSize()),
                    new LambdaQueryWrapper<Categories>()
                            .or().like(!StringUtils.isBlank(name), Categories::getName, name)
                            .or().like(!StringUtils.isBlank(description), Categories::getDescription, description));
        } else {
            // 如果不分页，查询所有数据
            categoriesPage = new Page<>(1, Integer.MAX_VALUE); // 使用一个大数作为页面大小，查询所有数据
            List<Categories> categories = baseMapper.selectList(new LambdaQueryWrapper<Categories>()
                    .or().like(!StringUtils.isBlank(name), Categories::getName, name)
                    .or().like(!StringUtils.isBlank(description), Categories::getDescription, description));
            categoriesPage.setTotal(categories.size());
            categoriesPage.setRecords(categories);
        }
        return new PageResult<>(categoriesPage.getTotal(), categoriesPage.getRecords());
    }

    /**
     * 批量删除图书分类
     *
     * @param ids 分类ids
     */
    @Transactional
    @Override
    public Boolean deleteBatch(List<Integer> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new ObjectNullException(MessageConstants.NULL);
        }

        // 使用 distinct() 去重，避免对重复的 id 做多次操作
        List<Integer> distinctIds = ids.stream().distinct().collect(Collectors.toList());

        // 存储错误信息的列表
        List<String> errorMessages = new ArrayList<>();

        // 遍历每个 ID，检查是否有书籍在上架
        distinctIds.forEach(id -> {
            Long count = booksMapper.selectCount(new LambdaQueryWrapper<Books>().eq(Books::getCategoryId, id).in(Books::getStatus, BookStatusConstants.ON_SHELF,  // 上架中
                    BookStatusConstants.CHECKED_OUT, // 已借出
                    BookStatusConstants.RESERVED,    // 预定
                    BookStatusConstants.UNDER_REPAIR));// 维修中

            // 如果有书籍在上架，记录错误信息
            if (count > 0) {
                errorMessages.add("分类id " + id + "存在书籍在上架");
            }
        });

        // 如果存在错误信息，则抛出异常，避免继续删除
        if (!errorMessages.isEmpty()) {
            throw new ObjectNullException(MessageConstants.DELETE_FAILED + ": " + StringUtils.join(", ", errorMessages));
        }
        // 执行批量删除
        return baseMapper.deleteBatchIds(distinctIds) > 0;
    }

    /**
     * 统计每个分类下的图书数量
     *
     * @return 分类统计列表
     */
    @Override
    public Map<String, Long> getCategoryStatistics() {
        List<Categories> categories = baseMapper.selectList(new LambdaQueryWrapper<Categories>().select(Categories::getCategoryId, Categories::getName));
        Map<String, Long> map = new HashMap<>();
        if (!categories.isEmpty()) {
            categories.forEach(category -> map.put(category.getName(), booksMapper.selectCount(new LambdaQueryWrapper<Books>().eq(Books::getCategoryId, category.getCategoryId()))));

        }
        return map;
    }


}
